import { _decorator, Component, Node, Prefab, instantiate, Vec3 } from "cc";
import { Player } from "../../prefabs/game/Player";
import { UserInfo } from "../../prefabs/game/UserInfo";
import event from "../../utils/event";
import request from "../../utils/request";
import websocket from "../../utils/websocket";
import { VisualAngle } from "../ui/Panel";
const { ccclass, property } = _decorator;

@ccclass("Game/Controllers/Players")
export class Players extends Component {
    @property(Prefab)
    private playerPrefab: Prefab = null;

    private userInfo = null;
    private players: Node[] = [];

    start() {
        event.on("game::enter", this.startGame, this);
        // this.startGame({ id: "QkjnfXo", name: "国色天香", url: "ws://localhost:3001" });
        event.on("panel.camera", this.updateUIPanel, this);
        event.on("panel.visual", this.onVisualSwitch, this);

        websocket.on("ws::connected", this.onWSConnected, this);
        websocket.on("game::enter", this.onGameEnter, this);
        websocket.on("player::create", this.onPlayerCreate, this);
        websocket.on("player::sync", this.onPlayerSync, this);
    }

    onDestroy() {
        event.off("game::enter");
        websocket.off("ws::connected");
        websocket.off("game::enter");
        websocket.off("player::create");
        websocket.off("player::sync");
    }

    startGame(server) {
        const token = localStorage.getItem("token");
        request.post("/users/userinfo", { token }).then(({ data }) => {
            this.userInfo = data;
            event.emit("game::userinfo", data);
            websocket.connect({ url: server.url, token });
        });
    }

    onGameEnter(data) {
        let hasMe = false;
        for (const playerData of data) {
            hasMe = playerData.userId === this.userInfo.userId;
            this.onPlayerCreate(playerData);
        }

        if (!hasMe) {
            const mine = { pos: { x: 2, y: 2, z: 0 }, euler: { x: 0, y: 0, z: 0 } };
            // this.onPlayerCreate(mine);
            websocket.send("player::create", mine);
        }
        this.scheduleOnce(() => this.updateUIPanel(), 0);
    }

    onWSConnected() {
        websocket.send("game::enter");
    }

    onPlayerCreate(data) {
        const { userId, pos, euler } = data;
        const player = instantiate(this.playerPrefab);
        // const userInfo = instantiate(this.userInfoPrefab);

        player.setPosition(pos.x, pos.y, pos.z);
        player.setRotationFromEuler(euler.x, euler.y, euler.z);
        player.getComponent(Player).init(data, userId === this.userInfo.userId);
        const mountPos = player.getComponent(Player).getUIMountPos();
        event.emit("ui::userinfopos", [{ userId: data.userId, pos: mountPos }]);

        // userInfo.active = false;
        // userInfo.getComponent(UserInfo).init(data, userId === this.userInfo.userId);

        this.players.push(player);
        this.node.addChild(player);
        // this.userInfoList.push(userInfo);
        // this.gamePanel.addChild(userInfo);
    }

    onPlayerSync(data) {
        let posArr: { userId: string; pos: Vec3 }[] = [];
        for (const item of data) {
            const player = this.players.find((_) => _.getComponent(Player).userId === item.userId);
            if (player) {
                player.getComponent(Player).sync(item);
                const pos = player.getComponent(Player).getUIMountPos();
                posArr.push({ userId: item.userId, pos });
                // const userInfo = this.userInfoList.find((_) => _.getComponent(UserInfo).userId === item.userId);
                // userInfo.getComponent(UserInfo).sync(pos);
            }
        }
        event.emit("ui::userinfopos", posArr);
    }

    updateUIPanel() {
        let posArr: { userId: string; pos: Vec3 }[] = [];
        for (const player of this.players) {
            const comp = player.getComponent(Player);
            const pos = comp.getUIMountPos();
            posArr.push({ userId: comp.userId, pos });
        }
        event.emit("ui::userinfopos", posArr);
    }

    onVisualSwitch(visual: VisualAngle) {
        const player = this.players.find((_) => _.getComponent(Player).userId === this.userInfo.userId);
        if (player) {
            player.getComponent(Player).switchVisual(visual === VisualAngle.Third);
        }
    }
}
